<?
class BuildExpression
	{
		var $aTerminos;
		
		function valueToDB ( $cValue )
			{
				if ( !empty($cValue) ) 
				{
					if ( is_numeric ( $cValue ) )
					{
						return $cValue;
					} else
					{
						return "'$cValue'";
					}
				} else return " null ";
			}
		function addKey( $cField, $cValue )
		{
			if ( !empty($cValue) ) 
			{
				$aKeys = explode( " ", $cValue );
				$cExpression = "";
				foreach( $aKeys as $cKey )
				{
					$cExpression .= "AND $cField like '% " . $cKey . "%' ";
				}
				$this->aTerminos[$cField] = array( 'cValue' => " (" . substr ( $cExpression , 4 ) . ")", 'cOperator'=> 'expression', 'cLogic' => $cLogic );
			}
		}
		function addArray ( $aData , $cPrefix = '' )
			{
				foreach ( $aData as $cField => $oTermino )
				{
					if ( !empty($oTermino) ) 
					{
						if ( $cPrefix && strpos($cField, '.') === false ) $cField = $cPrefix . '.' .$cField;
						if ( is_array($oTermino) )
						{
							if ( $oTermino[cPrefix] && strpos($cField, '.') === false ) $cField = $oTermino[cPrefix] . '.' .$cField;
							$this->add($cField, $oTermino[cValue],  $oTermino[cOperator] , '', '', $oTermino[cLogic] );
						} else
							$this->add($cField, $oTermino );
					}
				}
			}
		function addNull( $cField, $bCondition = true,  $cLogic  = 'AND' )
		{
			if ( $bCondition )
			{
				$this->aTerminos[$cField] = array( 'cValue' => "$cField IS NULL", 'cOperator'=> 'expression', 'cLogic' => $cLogic );
			}
		}
		function addBool( $cField, $bValue ,  $cLogic  = 'AND' )
		{
			if ( isset($bValue) ) 
			{
				$this->aTerminos[$cField] = array( 'cValue' => " ifnull($cField, 1) = " . ($bValue == 1 ? 1:0), 'cOperator'=> 'expression', 'cLogic' => $cLogic );
			}
		}
		function addNotNull( $cField, $bCondition = true,  $cLogic  = 'AND' )
		{
			if ( $bCondition )
			{
				$this->aTerminos[$cField] = array( 'cValue' => "$cField IS NOT NULL", 'cOperator'=> 'expression', 'cLogic' => $cLogic );
			}
		}
		function addExpression( $cField, $cExpression,  $cLogic  = 'AND' )
		{
			$this->aTerminos[$cField] = array( 'cValue' =>$cExpression, 'cOperator'=> 'expression', 'cLogic' => $cLogic );
		}
		function replace( $cField, $cFieldNew, $cOperator = '',  $cTable ='', $cCondition= '',  $cLogic  = 'AND' )
		{
			$cValue= $this->aTerminos[$cField][cValue];
			if ( !empty($cValue) )
			{
				if ( $cOperator == '' ) $cOperator = $this->aTerminos[$cField][cOperator];
				unset($this->aTerminos[$cField]);
				$this->add( $cFieldNew, $cValue, $cOperator,  $cTable, $cCondition,  $cLogic );
			} 
		}
		function add( $cField, $cValue, $cOperator = '=',  $cTable ='', $cCondition= '',  $cLogic  = 'AND' )
			{
				if ( !empty($cValue) )
				{
					$this->aTerminos[$cField] = array( 'cValue' => $cValue, 'cTable' =>$cTable, 'cCondition' => $cCondition, 'cOperator'=>$cOperator, 'cLogic' => $cLogic );
				}
			}
		function make()
			{
				$cJoin = $cWhere = '';
				foreach($this->aTerminos as $cField=> $aTermino )
				{
					$cWhere .= ( $aTermino[cLogic] ) ? ' ' .$aTermino[cLogic]  . ' ':  ' AND ';
					if ( $aTermino[cTable] )
					{
						$cJoin .= " JOIN " . $aTermino[cTable] . " ON " . $aTermino[cCondition]; 
					} 
					switch( $aTermino[cOperator] )
					{
						default: case '=': case 'igual':
							if ( is_numeric($aTermino[cValue]) )
								$cWhere .= " $cField = " . $this->valueToDb($aTermino[cValue]);
							else
								$cWhere .= " $cField like '%" . $aTermino[cValue] . "%' ";
							break;
						case 'x': case 'expression':
							$cWhere .= $aTermino[cValue];
							break;
						case '>': case 'mayor':
							$cWhere .= " $cField > " . $this->valueToDb($aTermino[cValue]);
							break;
						case '<': case 'menor':
							$cWhere .= " $cField < " . $this->valueToDb($aTermino[cValue]);
							break;
						case 'i': case 'in':
							$cWhere .= " $cField in ( " . $aTermino[cValue] . ") ";
							break;
						case 'b': case 'between':
							list ( $cValorA, $cValorB ) = explode ( ',', $aTermino[cValue] );
							$cWhere .= " $cField between " . $this->valueToDb($cValorA) . " AND " . $this->valueToDb($cValorB) . " ";
							break;
						case '*': case 'like':
							$cWhere .= " $cField like '%" . $aTermino[cValue] . "' ";
							break;
					}
				}
				
				return $cWhere ? $cJoin  . ' WHERE ' . substr($cWhere, 4 ) : $cJoin ;
			}
		function reset()
		{
			unset( $this->aTerminos );
		}
	}
		
class BuildExpressionOld
	{
		var $cExpression;
		var $cExpressionOperator = ' AND ';
		function setOperator ( $cOperator )
		{
			$this->cExpressionOperator = ' ' . $cOperator . ' ';
		}
		function reset()
		{
			$this->cExpression= "";
		}
		function addKey( $cField, $cValue )
		{
			if ( !empty($cValue) ) 
			{
				$aKeys = explode( " ", $cValue );
				$cExpression = "";
				foreach( $aKeys as $cKey )
				{
					$cExpression .= "AND $cField like '% " . $cKey . "%' ";
				}
				$this->cExpression .= $this->cExpressionOperator . " (" . substr ( $cExpression , 4 ) . ")";
			}
		}
		function addArray ( $aData , $cPrefix = '' )
			{
				foreach ( $aData as $cField => $cValue )
				{
					if ( !empty($cValue) ) 
					{
						$cOperator = ( !is_numeric( $cValue ) ) ? ' Like ' : ' = ' ;
						$this->cExpression .= $this->cExpressionOperator . " $cPrefix$cField $cOperator " . $this->valueToDb($cValue);
					}
				}
			}
		function make( $cPrefix = 'Where' )
			{
				if ( $this->cExpression )
				{
					return ' ' . $cPrefix . ' ' . substr( $this->cExpression, strlen ( $this->cExpressionOperator ) );
				}
			}
		function add( $cField, $cValue )
			{
				if ( !empty($cValue) ) 
				{
					$cOperator = ''; $nPos = 0;
					// Si empieza con ! es un NOT 
					if ( $cValue{0} == '!' ) 
					{
						$cOperator = ' Not ';
						$nPos ++;
					}
					$aOperadores = array( '=' => 1, '>' => 1, '<' => 1,'*' => 4, 'i' => 2, 'b' => 3);
					if ( array_key_exists ($cValue{$nPos} , $aOperadores ) )
					{
						$nTipoOperador =  $aOperadores[$cValue{$nPos}];
						if ( $nTipoOperador == 1 ) $cOperator .=  $cValue{$nPos} ;
						$nPos++;
					}
					// Si no entro en ninguno => el default es = 
					if ( $nPos == 0 ) $cOperator = '=';
					else $cValue = substr($cValue,$nPos);
					switch( $nTipoOperador ) 
					{
						default: case 1: // =, >, <
						$this->cExpression .= $this->cExpressionOperator . " $cField $cOperator  " . $this->valueToDb($cValue);
							break;
						case 2: // in ( Lista )
							$this->cExpression .= $this->cExpressionOperator . " $cField $cOperator in ( $cValue ) " ; 
							break;
						case 3: // between A and B
							$aValue = explode(',', substr($cValue,$nPos+2) );
							$cValueA= $this->valueToDb($aValue[0]);
							$cValueB= $this->valueToDb($aValue[1]);
							$this->cExpression .= $this->cExpressionOperator . " $cField $cOperator between $cValueA AND $cValueB "; 
							break;
						case 4: // like '%%'
							$this->cExpression .= $this->cExpressionOperator . " $cField $cOperator like '%$cValue%' "; 
							break;
					}
				}
			}
		function addBool( $cField, $cValue )
			{
				if ( $cValue == 1 || $cValue === 0) 
				{
					$this->cExpression .= $this->cExpressionOperator . " $cField =  $cValue" ;
				}
			}
		function addOperator ( $cField, $cOperator, $cValue )
			{
				if ( !empty($cValue) ) 
				{
					$this->cExpression .= $this->cExpressionOperator . " $cField $cOperator " . $this->valueToDb($cValue);
				}
			}
		function valueToDB ( $cValue , $bLike = false)
			{
				if ( is_numeric ( $cValue ) )
				{
					return $cValue;
				} elseif ( is_string ( $cValue ) && $bLike )
				{
					return " '%$cValue%' " ;
				} else
				{
					return "'$cValue'";
				}
			}
		function addExpression ( $cExpression, $bCondition = true )
			{
				if ( $bCondition ) 
				{
					$this->cExpression .= $this->cExpressionOperator . " ( $cExpression ) ";
				}
			}
	}
?>